package com.probiz.estore.sales.service.impl;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.dao.DataIntegrityViolationException;

import com.probiz.estore.Constants;
import com.probiz.estore.common.helper.ConfigUtil;
import com.probiz.estore.common.model.sales.GiftCertificate;
import com.probiz.estore.core.search.SearchCriteria;
import com.probiz.estore.core.service.impl.GenericManagerImpl;
import com.probiz.estore.exception.GiftCertificateStateException;
import com.probiz.estore.sales.SalesConstants;
import com.probiz.estore.sales.dao.GiftCertificateDao;
import com.probiz.estore.sales.model.GiftCertificateSearchCriteria;
import com.probiz.estore.sales.util.GenerateCodeUtil;
import com.probiz.estore.system.service.MsgSendManager;
import com.probiz.estore.system.util.MsgTemplateConstants;

public class GiftCertificateManagerImpl extends GenericManagerImpl<GiftCertificate> implements com.probiz.estore.sales.service.GiftCertificateManager {
	
	private MsgSendManager msgSendManager = null;

	private GiftCertificateDao giftCertificateDao = null;

	public void setGiftCertificateDao(GiftCertificateDao giftCertificateDao) {
		this.giftCertificateDao = giftCertificateDao;
	}

	protected void initManager() {
		dao = giftCertificateDao;
	}

	protected void preDelete(GiftCertificate entity) {
	}

	protected void preSave(GiftCertificate entity) {
	}

	public GiftCertificate getGiftCertificate(String giftCertificateNo) {
		return giftCertificateDao.getGiftCertificate(giftCertificateNo);
	}
	
	public void setMsgSendManager(MsgSendManager msgSendManager) {
		this.msgSendManager = msgSendManager;
	}


	public void sendGiftCertificate(GiftCertificate gc, String orderNo) {
		if (null != orderNo && !orderNo.equals("")) {
			gc.setOrderNo(orderNo);
		}
		if (Constants.FLAG_TRUE.equals(gc.getIsSentByEmail())) {
			// Sends email at once.
			Map model = new HashMap();
			model.put("giftCertificate", gc);
			msgSendManager.sendMsg(MsgTemplateConstants.MESSAGE_GIFT_CERTIFICATE, model, new String[] { gc.getRecipientEmail() }, null, null);
		}
	}

	public List<GiftCertificate> searchGiftCertificates(SearchCriteria _searchCriteria, GiftCertificateSearchCriteria _giftCertificateSearchCriteria) {
		return giftCertificateDao.searchGiftCertificates(_searchCriteria, _giftCertificateSearchCriteria);
	}

	private String generateGiftCertificateNo() {
		String no = GenerateCodeUtil.generateGiftCertificateNo();
		int j = 0;
		while (giftCertificateDao.existGiftCertificateNo(no)) {
			j++;
			if (j > SalesConstants.MAX_GEN_TRY_TIMES) {
				logger.error("GiftCertificateNo is repeat. MAX_TRY_NUM[" + SalesConstants.MAX_GEN_TRY_TIMES + "]");
				throw new DataIntegrityViolationException("GiftCertificateNo is repeat.");
			}
			no = GenerateCodeUtil.generateGiftCertificateNo();
		}
		return no;
	}

	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.sales.service.GiftCertificateManager#createGiftCertificate4Order(com.probiz.estore.common.model.sales.GiftCertificate)
	 */
	public GiftCertificate createGiftCertificate4Order(GiftCertificate giftCertificate) {
		giftCertificate.setCreateTime(new Date());
		giftCertificate.setGiftCertificateNo(this.generateGiftCertificateNo());
		giftCertificate.setExpireTime(giftCertificate.getDefaultGiftCertificateExpireTime());
		save(giftCertificate);

		return giftCertificate;
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.sales.service.GiftCertificateManager#createGiftCertificate4Admin(com.probiz.estore.common.model.sales.GiftCertificate)
	 */
	public GiftCertificate createGiftCertificate4Admin(GiftCertificate giftCertificate){
		giftCertificate.setRemainedAmt(giftCertificate.getGiftCertAmt());
		giftCertificate.setGiftCertificateNo(this.generateGiftCertificateNo());
		save(giftCertificate);
		return giftCertificate;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.sales.service.GiftCertificateManager#doUseGiftCertificate(java.lang.String, java.math.BigDecimal, java.lang.String)
	 */
	public void doUseGiftCertificate(String giftCertificateNo, BigDecimal decMoney,String orderNo) throws GiftCertificateStateException {
		GiftCertificate giftCertificate = getGiftCertificate(giftCertificateNo);
		if(null == giftCertificate){
			throw new GiftCertificateStateException(giftCertificateNo, GiftCertificate.STATE_INVALID);
		}
		short state = giftCertificate.getFrontState();
		if (GiftCertificate.STATE_AVAILABLE.equals(state)) {
			if (giftCertificate.getRemainedAmt().compareTo(new BigDecimal("0")) <= 0) {
				state = GiftCertificate.STATE_REMAINEDAMT_IS_ZERO;
			}
		}
		if (state == GiftCertificate.STATE_AVAILABLE) {

			if (decMoney.compareTo(giftCertificate.getRemainedAmt()) > 0) {
				// 余额不足够支付
				throw new GiftCertificateStateException(giftCertificateNo, GiftCertificate.STATE_NOT_ENOUGH_REMAINEDAMT);
			} else {
				// 余额足够支付
				giftCertificate.setRemainedAmt(giftCertificate.getRemainedAmt().add(decMoney.negate()));
				giftCertificate.setOrderNoInUse(orderNo);
				super.save(giftCertificate);
				return;
			}
		} else {
			throw new GiftCertificateStateException(giftCertificateNo, state);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.sales.service.GiftCertificateManager#doCompleteUseGiftCertificate(java.lang.String, java.math.BigDecimal, java.lang.String)
	 */
	public void doCompleteUseGiftCertificate(String giftCertificateNo, BigDecimal decMoney,String orderNo) throws GiftCertificateStateException{
//		GiftCertificate giftCertificate = getGiftCertificate(giftCertificateNo);
//		if(null == giftCertificate){
//			throw new GiftCertificateStateException(giftCertificateNo, GiftCertificate.STATE_INVALID);
//		}
//		this.save(giftCertificate);
		//DO NOTHING
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.sales.service.GiftCertificateManager#doReturnGiftCertificate(java.lang.String, java.math.BigDecimal)
	 */
	public void doReturnGiftCertificate(String giftCertificateNo, BigDecimal decMoney) {
		GiftCertificate giftCertificate = this.getGiftCertificate(giftCertificateNo);
		if (giftCertificate != null) {
			BigDecimal remaindedAmt = giftCertificate.getRemainedAmt().add(decMoney);
			if (remaindedAmt.compareTo(giftCertificate.getGiftCertAmt()) <= 0) {
				giftCertificate.setRemainedAmt(remaindedAmt);
				this.save(giftCertificate);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.sales.service.GiftCertificateManager#checkGiftcertificate(java.lang.String)
	 */
	public void checkGiftcertificate(String giftCertificateNo) throws GiftCertificateStateException {
		GiftCertificate giftCertificate = getGiftCertificate(giftCertificateNo);
		if(null == giftCertificate){
			throw new GiftCertificateStateException(giftCertificateNo, GiftCertificate.STATE_INVALID);
		}
		short state = giftCertificate.getFrontState();
		if (GiftCertificate.STATE_AVAILABLE.equals(state)) {
			if (giftCertificate.getRemainedAmt().compareTo(new BigDecimal("0")) <= 0) {
				state = GiftCertificate.STATE_REMAINEDAMT_IS_ZERO;
			}
		}
		if (state == GiftCertificate.STATE_AVAILABLE) {
		} else {
			throw new GiftCertificateStateException(giftCertificateNo, state);
		}
	}


	
}
